# Copyright 2022 The Centipede Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Description:
#   Centipede: an experimental distributed fuzzing engine.

load("@rules_proto//proto:defs.bzl", "proto_library")
load(":instrument.bzl", "cc_uninstrumented_binary")

VISIBILITY = ["//visibility:public"]

EXTENDED_API_VISIBILITY = VISIBILITY

PUBLIC_API_VISIBILITY = VISIBILITY

package(default_visibility = VISIBILITY)

licenses(["notice"])

################################################################################
#                                  Binaries
################################################################################

cc_binary(
    name = "centipede",
    srcs = ["centipede_main.cc"],
    deps = [
        ":centipede_callbacks",
        ":centipede_default_callbacks",
        ":centipede_interface",
        ":config_file",
        ":environment_flags",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/log:flags",
    ],
)

cc_uninstrumented_binary(
    name = "centipede_uninstrumented",
    binary = ":centipede",
    visibility = PUBLIC_API_VISIBILITY,
)

# A standalone seed corpus generator.
cc_binary(
    name = "seed_corpus_maker",
    srcs = ["seed_corpus_maker.cc"],
    deps = [
        ":config_init",
        ":seed_corpus_maker_flags",
        ":seed_corpus_maker_lib",
        ":util",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_binary(
    name = "blob_file_converter",
    srcs = ["blob_file_converter.cc"],
    deps = [
        ":config_init",
        ":rusage_profiler",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

###############################################################################
#                              Proto libraries
###############################################################################

# Configuration for the seed corpus maker.
proto_library(
    name = "seed_corpus_config_proto",
    srcs = ["seed_corpus_config.proto"],
)

cc_proto_library(
    name = "seed_corpus_config_cc_proto",
    visibility = EXTENDED_API_VISIBILITY,
    deps = [":seed_corpus_config_proto"],
)

################################################################################
#                             C++ libraries
################################################################################

# This lib must have zero non-trivial dependencies (other than libc).
cc_library(
    name = "int_utils",
    hdrs = ["int_utils.h"],
)

cc_library(
    name = "rolling_hash",
    hdrs = ["rolling_hash.h"],
)

cc_library(
    name = "symbol_table",
    srcs = ["symbol_table.cc"],
    hdrs = ["symbol_table.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":command",
        ":control_flow",
        ":pc_info",
        ":thread_pool",
        ":util",
        "@com_google_absl//absl/container:node_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "foreach_nonzero",
    hdrs = ["foreach_nonzero.h"],
)

# This lib must have zero non-trivial dependencies (other than libc). See feature.h.
cc_library(
    name = "feature",
    srcs = ["feature.cc"],
    hdrs = [
        "concurrent_bitset.h",  # TODO(kcc): consider moving to a separate cc_library.
        "concurrent_byteset.h",  # TODO(kcc): consider moving to a separate cc_library.
        "feature.h",
        "hashed_ring_buffer.h",  # TODO(kcc): consider moving to a separate cc_library.
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":rolling_hash",
        "@com_google_absl//absl/base:core_headers",  # exception, ok to depend on here.
    ],
)

cc_library(
    name = "pc_info",
    srcs = ["pc_info.cc"],
    hdrs = ["pc_info.h"],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:defs",
    ],
)

cc_library(
    name = "knobs",
    srcs = ["knobs.cc"],
    hdrs = ["knobs.h"],
    # Avoid non-trivial dependencies here, as this library will be linked to target binaries.
    deps = [
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:defs",
    ],
)

cc_library(
    name = "reverse_pc_table",
    hdrs = ["reverse_pc_table.h"],
    # Avoid non-trivial dependencies here, as this library will be linked to target binaries.
    deps = [
        ":pc_info",
        "@com_google_absl//absl/types:span",
    ],
)

cc_library(
    name = "callstack",
    hdrs = ["callstack.h"],
    # Avoid non-trivial dependencies here, as this library will be linked to target binaries.
    deps = [
        ":rolling_hash",
    ],
)

# Various utilities.
cc_library(
    name = "util",
    srcs = ["util.cc"],
    hdrs = ["util.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":feature",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "config_util",
    srcs = ["config_util.cc"],
    hdrs = ["config_util.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        "@com_google_absl//absl/flags:reflection",
        "@com_google_absl//absl/strings",
    ],
)

cc_library(
    name = "config_init",
    srcs = ["config_init.cc"],
    hdrs = ["config_init.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":config_util",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/base:log_severity",
        "@com_google_absl//absl/flags:config",
        "@com_google_absl//absl/flags:parse",
        "@com_google_absl//absl/log:globals",
        "@com_google_absl//absl/log:initialize",
        "@com_google_absl//absl/strings",
    ],
)

cc_library(
    name = "config_file",
    srcs = ["config_file.cc"],
    hdrs = ["config_file.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":config_init",
        ":config_util",
        ":util",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/flags:parse",
        "@com_google_absl//absl/flags:reflection",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "thread_pool",
    hdrs = ["thread_pool.h"],
    deps = [
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/functional:any_invocable",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/synchronization",
    ],
)

cc_library(
    name = "rusage_stats",
    srcs = ["rusage_stats.cc"],
    hdrs = ["rusage_stats.h"],
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/time",
    ],
)

cc_library(
    name = "rusage_profiler",
    srcs = ["rusage_profiler.cc"],
    hdrs = ["rusage_profiler.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":periodic_action",
        ":rusage_stats",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
    ],
)

cc_library(
    name = "resource_pool",
    srcs = ["resource_pool.cc"],
    hdrs = ["resource_pool.h"],
    deps = [
        ":rusage_stats",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
    ],
)

cc_library(
    name = "periodic_action",
    srcs = ["periodic_action.cc"],
    hdrs = ["periodic_action.h"],
    deps = [
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/functional:any_invocable",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
    ],
)

cc_library(
    name = "stats",
    srcs = ["stats.cc"],
    hdrs = ["stats.h"],
    linkopts = ["-latomic"],  # for std::atomic::load()/store().
    deps = [
        ":environment",
        ":workdir",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/container:btree",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/time",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "minimize_crash",
    srcs = ["minimize_crash.cc"],
    hdrs = ["minimize_crash.h"],
    deps = [
        ":centipede_callbacks",
        ":early_exit",
        ":environment",
        ":mutation_input",
        ":runner_result",
        ":thread_pool",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/synchronization",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "analyze_corpora",
    srcs = ["analyze_corpora.cc"],
    hdrs = ["analyze_corpora.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":binary_info",
        ":control_flow",
        ":corpus",
        ":corpus_io",
        ":coverage",
        ":feature",
        ":pc_info",
        ":workdir",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "shared_memory_blob_sequence",
    srcs = ["shared_memory_blob_sequence.cc"],
    hdrs = ["shared_memory_blob_sequence.h"],
    linkopts = ["-lrt"],  # for shm_open.
    visibility = PUBLIC_API_VISIBILITY,
    deps = ["@com_google_absl//absl/base:nullability"],
    # don't add any dependencies.
)

cc_library(
    name = "execution_metadata",
    srcs = ["execution_metadata.cc"],
    hdrs = ["execution_metadata.h"],
    deps = [
        # This target must have a minimal set of dependencies since it is
        # used in centipede_runner.
        "@com_google_fuzztest//common:defs",
        ":shared_memory_blob_sequence",
    ],
)

cc_library(
    name = "runner_result",
    srcs = ["runner_result.cc"],
    hdrs = ["runner_result.h"],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        # This target must have a minimal set of dependencies since it is
        # used in centipede_runner.
        ":feature",
        ":execution_metadata",
        ":shared_memory_blob_sequence",
    ],
)

cc_library(
    name = "runner_request",
    srcs = ["runner_request.cc"],
    hdrs = ["runner_request.h"],
    deps = [
        # This target must have a minimal set of dependencies since it is
        # used in centipede_runner.
        ":shared_memory_blob_sequence",
        ":execution_metadata",
        ":mutation_input",
        "@com_google_fuzztest//common:defs",
    ],
)

cc_library(
    name = "mutation_input",
    hdrs = ["mutation_input.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        # This target must have a minimal set of dependencies since it is
        # used in centipede_runner.
        "@com_google_fuzztest//common:defs",
        ":execution_metadata",
    ],
)

cc_library(
    name = "byte_array_mutator",
    srcs = ["byte_array_mutator.cc"],
    hdrs = ["byte_array_mutator.h"],
    visibility = PUBLIC_API_VISIBILITY,
    # Avoid non-trivial dependencies here, as this library will be linked to target binaries.
    deps = [
        ":execution_metadata",
        ":knobs",
        ":mutation_input",
        "@com_google_absl//absl/base:nullability",
        "@com_google_fuzztest//common:defs",
    ],
)

# Library for dealing with code coverage data from
# https://clang.llvm.org/docs/SanitizerCoverage.html.
cc_library(
    name = "coverage",
    srcs = [
        "coverage.cc",
    ],
    hdrs = [
        "coverage.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":control_flow",
        ":feature",
        ":pc_info",
        ":symbol_table",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/synchronization",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
    ],
)

# Library for dealing with control flow data from
# https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-control-flow.
cc_library(
    name = "control_flow",
    srcs = [
        "control_flow.cc",
    ],
    hdrs = [
        "control_flow.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":command",
        ":pc_info",
        ":util",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
    ],
)

# Library for dealing with call graph data from
# https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-control-flow.
cc_library(
    name = "call_graph",
    srcs = [
        "call_graph.cc",
    ],
    hdrs = [
        "call_graph.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":control_flow",
        ":pc_info",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "feature_set",
    srcs = ["feature_set.cc"],
    hdrs = ["feature_set.h"],
    deps = [
        ":control_flow",
        ":feature",
        ":util",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:logging",
    ],
)

# TODO(kcc): [impl] add dedicated unittests.
cc_library(
    name = "corpus",
    srcs = ["corpus.cc"],
    hdrs = ["corpus.h"],
    deps = [
        ":binary_info",
        ":control_flow",
        ":coverage",
        ":execution_metadata",
        ":feature",
        ":feature_set",
        ":util",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
    ],
)

cc_library(
    name = "command",
    srcs = ["command.cc"],
    hdrs = ["command.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":early_exit",
        ":util",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "binary_info",
    srcs = ["binary_info.cc"],
    hdrs = [
        "binary_info.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":call_graph",
        ":command",
        ":control_flow",
        ":pc_info",
        ":symbol_table",
        ":util",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "centipede_callbacks",
    srcs = [
        "centipede_callbacks.cc",
    ],
    hdrs = [
        "centipede_callbacks.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":binary_info",
        ":byte_array_mutator",
        ":command",
        ":control_flow",
        ":environment",
        ":fuzztest_mutator",
        ":mutation_input",
        ":runner_request",
        ":runner_result",
        ":shared_memory_blob_sequence",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "corpus_io",
    srcs = ["corpus_io.cc"],
    hdrs = ["corpus_io.h"],
    deps = [
        ":feature",
        ":rusage_profiler",
        ":util",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/time",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
    ],
)

cc_library(
    name = "early_exit",
    srcs = ["early_exit.cc"],
    hdrs = ["early_exit.h"],
    linkopts = ["-latomic"],  # for std::atomic::load()/store().
    visibility = PUBLIC_API_VISIBILITY,
)

cc_library(
    name = "environment_flags",
    srcs = ["environment_flags.cc"],
    hdrs = ["environment_flags.h"],
    defines = select({
        "@com_google_fuzztest//fuzztest:disable_riegeli": ["CENTIPEDE_DISABLE_RIEGELI"],
        "//conditions:default": [],
    }),
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":environment",
        ":util",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "centipede_lib",
    srcs = [
        "centipede.cc",
    ],
    hdrs = [
        "centipede.h",
    ],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":binary_info",
        ":centipede_callbacks",
        ":command",
        ":control_flow",
        ":corpus",
        ":corpus_io",
        ":coverage",
        ":early_exit",
        ":environment",
        ":feature",
        ":feature_set",
        ":mutation_input",
        ":pc_info",
        ":runner_result",
        ":rusage_profiler",
        ":rusage_stats",
        ":stats",
        ":symbol_table",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
    ],
)

cc_library(
    name = "centipede_interface",
    srcs = [
        "centipede_interface.cc",
    ],
    hdrs = [
        "centipede_interface.h",
    ],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":analyze_corpora",
        ":binary_info",
        ":centipede_callbacks",
        ":centipede_lib",
        ":command",
        ":coverage",
        ":distill",
        ":early_exit",
        ":environment",
        ":minimize_crash",
        ":pc_info",
        ":periodic_action",
        ":runner_result",
        ":seed_corpus_config_cc_proto",
        ":seed_corpus_maker_lib",
        ":stats",
        ":thread_pool",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/time",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
        "@com_google_fuzztest//fuzztest:configuration",
    ],
)

cc_library(
    name = "environment",
    srcs = [
        "environment.cc",
    ],
    hdrs = [
        "environment.h",
    ],
    defines = select({
        "@com_google_fuzztest//fuzztest:disable_riegeli": ["CENTIPEDE_DISABLE_RIEGELI"],
        "//conditions:default": [],
    }),
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":feature",
        ":knobs",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
    ],
)

cc_library(
    name = "distill",
    srcs = ["distill.cc"],
    hdrs = ["distill.h"],
    deps = [
        ":corpus_io",
        ":environment",
        ":feature",
        ":feature_set",
        ":periodic_action",
        ":resource_pool",
        ":rusage_profiler",
        ":rusage_stats",
        ":thread_pool",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
    ],
)

cc_library(
    name = "centipede_default_callbacks",
    srcs = ["centipede_default_callbacks.cc"],
    hdrs = ["centipede_default_callbacks.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":centipede_callbacks",
        ":environment",
        ":mutation_input",
        ":runner_result",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "fuzztest_mutator",
    srcs = ["fuzztest_mutator.cc"],
    hdrs = ["fuzztest_mutator.h"],
    deps = [
        ":byte_array_mutator",
        ":execution_metadata",
        ":knobs",
        ":mutation_input",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//fuzztest:coverage",
        "@com_google_fuzztest//fuzztest:domain_core",
    ],
)

cc_library(
    name = "weak_sancov_stubs",
    srcs = ["weak_sancov_stubs.cc"],
    visibility = PUBLIC_API_VISIBILITY,
    alwayslink = 1,
)

# runner_fork_server can be linked to a binary or used directly as a .so via LD_PRELOAD.
cc_library(
    name = "runner_fork_server",
    srcs = ["runner_fork_server.cc"],
    visibility = PUBLIC_API_VISIBILITY,
    deps = ["@com_google_absl//absl/base:nullability"],
    alwayslink = 1,  # Otherwise the linker drops the fork server.
)

cc_library(
    name = "runner_cmp_trace",
    hdrs = ["runner_cmp_trace.h"],
)

# Library for manipulating centipede runner flags. This is not used by the
# runner itself but by other tools.
cc_library(
    name = "runner_flags",
    srcs = ["runner_flags.cc"],
    hdrs = ["runner_flags.h"],
    visibility = PUBLIC_API_VISIBILITY,
    # This has no dependency and only uses string, pair and vector.
)

# The runner library is special:
#   * It must not be instrumented with asan, sancov, etc.
#   * It must not have heavy dependencies, and ideally not at all.
#     Exceptions are STL and absl::span (temporarily, until we can switch to
#     std::span).
#   * The bazel rule :centipede_runner must produce a self-contained .a file
#     with all
#     objects in it, which means the build rule must not depend other .a rules.
#
#  Some of the .cc and .h files used by the runner are also used by the engine,
#  e.g. feature.cc. These files are compiled by the engine and the runner
#  separately, with different compiler flags.
RUNNER_SOURCES_NO_MAIN = [
    "byte_array_mutator.cc",
    "byte_array_mutator.h",
    "callstack.h",
    "concurrent_bitset.h",
    "concurrent_byteset.h",
    "execution_metadata.cc",
    "execution_metadata.h",
    "runner_request.cc",
    "runner_request.h",
    "runner_result.cc",
    "runner_result.h",
    "feature.cc",
    "feature.h",
    "foreach_nonzero.h",
    "hashed_ring_buffer.h",
    "int_utils.h",
    "knobs.h",
    "knobs.cc",
    "mutation_input.h",
    "pc_info.h",
    "reverse_pc_table.h",
    "rolling_hash.h",
    "runner.cc",
    "runner.h",
    "runner_dl_info.h",
    "runner_dl_info.cc",
    "runner_sancov_object.h",
    "runner_sancov_object.cc",
    "runner_utils.h",
    "runner_utils.cc",
    "runner_cmp_trace.h",
    "runner_fork_server.cc",
    "runner_interceptors.cc",
    "runner_interface.h",
    "runner_sancov.cc",
    "shared_memory_blob_sequence.cc",
    "shared_memory_blob_sequence.h",
    "@com_google_fuzztest//common:defs.h",
]

RUNNER_SOURCES_WITH_MAIN = RUNNER_SOURCES_NO_MAIN + ["runner_main.cc"]

# Disable sancov and sanitizer instrumentation
RUNNER_COPTS = [
    "-fsanitize-coverage=0",
    "-fno-sanitize=address,hwaddress,memory,thread,undefined",
]

RUNNER_SANITIZED_COPTS = [
    "-fsanitize-coverage=0",
]

RUNNER_LINKOPTS = [
    "-ldl",  # for dlsym
    "-lrt",  # for shm_open
    "-lpthread",  # for pthread_once
]

# WARNING: be careful with more deps here. Use only the most trivial ones.
RUNNER_DEPS = [
    "@com_google_absl//absl/types:span",
    "@com_google_absl//absl/base:core_headers",
    "@com_google_absl//absl/numeric:bits",
]

# A fuzz target needs to link with this library in order to run with Centipede.
# The fuzz target must provide its own main().
#
# See also comments above RUNNER_SOURCES_NO_MAIN.
#
cc_library(
    name = "centipede_runner_no_main",
    srcs = RUNNER_SOURCES_NO_MAIN,
    hdrs = ["runner_interface.h"],
    copts = RUNNER_COPTS,
    linkopts = RUNNER_LINKOPTS,
    linkstatic = True,  # Must be linked statically even when dynamic_mode=on.
    visibility = ["//visibility:public"],
    deps = RUNNER_DEPS + ["@com_google_absl//absl/base:nullability"],
)

# Same as :centipede_runner_no_main, except it can be sanitized to avoid false
# positives like
# https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow#false-positives
cc_library(
    name = "centipede_runner_no_main_sanitized",
    srcs = RUNNER_SOURCES_NO_MAIN,
    hdrs = ["runner_interface.h"],
    copts = RUNNER_SANITIZED_COPTS,
    linkopts = RUNNER_LINKOPTS,
    linkstatic = True,  # Must be linked statically even when dynamic_mode=on.
    visibility = ["//visibility:public"],
    deps = RUNNER_DEPS + ["@com_google_absl//absl/base:nullability"],
)

# Same as :centipede_runner_no_main but as a DSO. Experimental.
cc_binary(
    name = "centipede_runner_no_main.so",
    srcs = RUNNER_SOURCES_NO_MAIN,
    copts = RUNNER_COPTS,
    linkopts = RUNNER_LINKOPTS,
    linkshared = 1,
    visibility = ["//visibility:public"],
    deps = RUNNER_DEPS + ["@com_google_absl//absl/base:nullability"],
)

# A full self-contained library archive that external clients should link to
# their fuzz targets to make them compatible with the Centipede fuzzing engine
# (the `:centipede` target in this BUILD).
cc_library(
    name = "centipede_runner",
    srcs = RUNNER_SOURCES_WITH_MAIN,
    hdrs = ["runner_interface.h"],
    copts = RUNNER_COPTS,
    linkopts = RUNNER_LINKOPTS,
    linkstatic = True,  # Must be linked statically even when dynamic_mode=on.
    visibility = ["//visibility:public"],
    deps = RUNNER_DEPS + ["@com_google_absl//absl/base:nullability"],
)

# Utilities for seed corpus generation.
cc_library(
    name = "seed_corpus_maker_lib",
    srcs = ["seed_corpus_maker_lib.cc"],
    hdrs = ["seed_corpus_maker_lib.h"],
    visibility = EXTENDED_API_VISIBILITY,
    deps = [
        ":corpus_io",
        ":feature",
        ":rusage_profiler",
        ":seed_corpus_config_cc_proto",
        ":thread_pool",
        ":util",
        ":workdir",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:status_macros",
        "@com_google_protobuf//:protobuf",
    ],
)

# Flags for :seed_corpus_maker.
cc_library(
    name = "seed_corpus_maker_flags",
    srcs = ["seed_corpus_maker_flags.cc"],
    hdrs = ["seed_corpus_maker_flags.h"],
    deps = ["@com_google_absl//absl/flags:flag"],
)

################################################################################
#                        General-purpose testing utilities
################################################################################

cc_library(
    name = "workdir",
    srcs = ["workdir.cc"],
    hdrs = ["workdir.h"],
    visibility = PUBLIC_API_VISIBILITY,
    deps = [
        ":environment",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_fuzztest//common:logging",
    ],
)

cc_library(
    name = "test_coverage_util",
    testonly = True,
    srcs = ["test_coverage_util.cc"],
    hdrs = ["test_coverage_util.h"],
    deps = [
        ":centipede_callbacks",
        ":corpus",
        ":environment",
        ":feature",
        ":mutation_input",
        ":runner_result",
        ":util",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:defs",
    ],
)

sh_library(
    name = "test_fuzzing_util_sh",
    srcs = ["test_fuzzing_util.sh"],
)

sh_library(
    name = "test_util_sh",
    srcs = ["test_util.sh"],
    data = [
    ],
)

################################################################################
#                               Unit tests
################################################################################

cc_test(
    name = "binary_info_test",
    srcs = ["binary_info_test.cc"],
    deps = [
        ":binary_info",
        ":pc_info",
        ":symbol_table",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "environment_test",
    srcs = ["environment_test.cc"],
    deps = [
        ":environment",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "workdir_test",
    srcs = ["workdir_test.cc"],
    deps = [
        ":environment",
        ":workdir",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "pc_info_test",
    srcs = ["pc_info_test.cc"],
    deps = [
        ":pc_info",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "rolling_hash_test",
    srcs = ["rolling_hash_test.cc"],
    deps = [
        ":feature",
        ":rolling_hash",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "symbol_table_test",
    srcs = ["symbol_table_test.cc"],
    deps = [
        ":symbol_table",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "util_test",
    srcs = ["util_test.cc"],
    copts = ["-fno-signed-char"],
    deps = [
        ":feature",
        ":thread_pool",
        ":util",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/log",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "config_util_test",
    srcs = ["config_util_test.cc"],
    deps = [
        # Include this just to get some flags external to the test itself.
        ":environment",  # buildcleaner:keep
        ":config_util",
        ":environment_flags",
        "@com_google_fuzztest//common:logging",
        "@com_google_googletest//:gtest_main",
        "@com_google_absl//absl/flags:flag",
    ],
)

cc_test(
    name = "config_file_test",
    srcs = ["config_file_test.cc"],
    deps = [
        ":config_file",
        "@com_google_googletest//:gtest_main",
        # Defines FLAGS_flagfile.
        "@com_google_absl//absl/flags:parse",  # buildcleaner:keep
    ],
)

cc_test(
    name = "rusage_stats_test",
    size = "medium",
    timeout = "long",
    srcs = ["rusage_stats_test.cc"],
    deps = [
        ":rusage_stats",
        ":thread_pool",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "distill_test",
    srcs = ["distill_test.cc"],
    deps = [
        ":corpus_io",
        ":distill",
        ":environment",
        ":feature",
        ":util",
        ":workdir",
        "@com_google_absl//absl/flags:reflection",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "rusage_profiler_test",
    # Allocates large blocks of memory to fight small number volatility.
    size = "large",
    timeout = "long",
    srcs = ["rusage_profiler_test.cc"],
    deps = [
        ":rusage_profiler",
        ":rusage_stats",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/time",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "stats_test",
    srcs = ["stats_test.cc"],
    deps = [
        ":environment",
        ":stats",
        ":util",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/log:log_entry",
        "@com_google_absl//absl/log:log_sink",
        "@com_google_absl//absl/log:log_sink_registry",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "minimize_crash_test",
    srcs = ["minimize_crash_test.cc"],
    deps = [
        ":centipede_callbacks",
        ":environment",
        ":minimize_crash",
        ":runner_result",
        ":util",
        ":workdir",
        "@com_google_absl//absl/base:nullability",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "analyze_corpora_test",
    srcs = ["analyze_corpora_test.cc"],
    data = [
        "@com_google_fuzztest//centipede/testing:test_fuzz_target",
        "@com_google_fuzztest//centipede/testing:test_fuzz_target_trace_pc",
        "@com_google_fuzztest//centipede/testing:threaded_fuzz_target",
    ],
    deps = [
        ":analyze_corpora",
        ":binary_info",
        ":environment",
        ":symbol_table",
        ":test_coverage_util",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:remote_file",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "shared_memory_blob_sequence_test",
    srcs = ["shared_memory_blob_sequence_test.cc"],
    deps = [
        ":shared_memory_blob_sequence",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "execution_metadata_test",
    srcs = ["execution_metadata_test.cc"],
    deps = [
        ":execution_metadata",
        ":shared_memory_blob_sequence",
        "@com_google_fuzztest//common:defs",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "runner_result_test",
    srcs = ["runner_result_test.cc"],
    deps = [
        ":execution_metadata",
        ":feature",
        ":runner_result",
        ":shared_memory_blob_sequence",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "mutation_input_test",
    srcs = ["mutation_input_test.cc"],
    deps = [
        ":mutation_input",
        "@com_google_fuzztest//common:defs",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "byte_array_mutator_test",
    srcs = ["byte_array_mutator_test.cc"],
    deps = [
        ":byte_array_mutator",
        ":execution_metadata",
        ":knobs",
        ":mutation_input",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_fuzztest//common:defs",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "feature_test",
    srcs = ["feature_test.cc"],
    deps = [
        ":feature",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "foreach_nonzero_test",
    srcs = ["foreach_nonzero_test.cc"],
    deps = [
        ":foreach_nonzero",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "fuzztest_mutator_test",
    srcs = ["fuzztest_mutator_test.cc"],
    deps = [
        ":execution_metadata",
        ":fuzztest_mutator",
        ":knobs",
        ":mutation_input",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:defs",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "knobs_test",
    srcs = ["knobs_test.cc"],
    deps = [
        ":knobs",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/types:span",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "reverse_pc_table_test",
    srcs = ["reverse_pc_table_test.cc"],
    deps = [
        ":pc_info",
        ":reverse_pc_table",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "callstack_test",
    srcs = ["callstack_test.cc"],
    deps = [
        ":callstack",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_fuzztest//common:defs",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "feature_set_test",
    srcs = ["feature_set_test.cc"],
    deps = [
        ":feature",
        ":feature_set",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "corpus_io_test",
    srcs = ["corpus_io_test.cc"],
    deps = [
        ":corpus",
        ":corpus_io",
        ":feature",
        ":util",
        ":workdir",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/types:span",
        "@com_google_fuzztest//common:blob_file",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "corpus_test",
    srcs = ["corpus_test.cc"],
    deps = [
        ":binary_info",
        ":call_graph",
        ":control_flow",
        ":corpus",
        ":feature",
        ":feature_set",
        ":pc_info",
        ":util",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_binary(
    name = "command_test_helper",
    srcs = ["command_test_helper.cc"],
    deps = [
        ":runner_fork_server",
        "@com_google_absl//absl/base:nullability",
    ],
)

cc_test(
    name = "command_test",
    srcs = ["command_test.cc"],
    data = [":command_test_helper"],
    deps = [
        ":command",
        ":early_exit",
        ":util",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "runner_cmp_trace_test",
    srcs = ["runner_cmp_trace_test.cc"],
    deps = [
        ":runner_cmp_trace",
        "@com_google_absl//absl/base:nullability",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "control_flow_test",
    srcs = ["control_flow_test.cc"],
    data = [
        "@com_google_fuzztest//centipede/testing:test_fuzz_target",
        "@com_google_fuzztest//centipede/testing:test_fuzz_target_trace_pc",
        "@com_google_fuzztest//centipede/testing:threaded_fuzz_target",
    ],
    deps = [
        ":binary_info",
        ":control_flow",
        ":pc_info",
        ":symbol_table",
        ":thread_pool",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "call_graph_test",
    srcs = ["call_graph_test.cc"],
    deps = [
        ":call_graph",
        ":control_flow",
        ":pc_info",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_fuzztest//common:logging",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "runner_flags_test",
    srcs = ["runner_flags_test.cc"],
    deps = [
        ":runner_flags",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "seed_corpus_maker_lib_test",
    srcs = ["seed_corpus_maker_lib_test.cc"],
    deps = [
        ":feature",
        ":seed_corpus_config_cc_proto",
        ":seed_corpus_maker_lib",
        ":workdir",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:status_macros",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
        "@com_google_protobuf//:protobuf",
    ],
)

cc_test(
    name = "coverage_test",
    srcs = ["coverage_test.cc"],
    data = [
        "@com_google_fuzztest//centipede/testing:test_fuzz_target",
        "@com_google_fuzztest//centipede/testing:test_fuzz_target_trace_pc",
        "@com_google_fuzztest//centipede/testing:threaded_fuzz_target",
    ],
    deps = [
        ":binary_info",
        ":control_flow",
        ":coverage",
        ":environment",
        ":feature",
        ":pc_info",
        ":symbol_table",
        ":test_coverage_util",
        ":thread_pool",
        ":util",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "resource_pool_test",
    srcs = ["resource_pool_test.cc"],
    deps = [
        ":resource_pool",
        ":rusage_stats",
        ":thread_pool",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "periodic_action_test",
    srcs = ["periodic_action_test.cc"],
    deps = [
        ":periodic_action",
        "@com_google_absl//absl/synchronization",
        "@com_google_absl//absl/time",
        "@com_google_fuzztest//common:logging",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "concurrent_bitset_test",
    srcs = ["concurrent_bitset_test.cc"],
    deps = [
        ":feature",
        ":thread_pool",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "concurrent_byteset_test",
    srcs = ["concurrent_byteset_test.cc"],
    deps = [
        ":feature",
        ":thread_pool",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "hashed_ring_buffer_test",
    srcs = ["hashed_ring_buffer_test.cc"],
    deps = [
        ":feature",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "int_utils_test",
    srcs = ["int_utils_test.cc"],
    deps = [
        ":int_utils",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_googletest//:gtest_main",
    ],
)

################################################################################
#                               Other tests
################################################################################

cc_test(
    name = "centipede_test",
    timeout = "long",
    srcs = ["centipede_test.cc"],
    data = [
        "@com_google_fuzztest//centipede/testing:abort_fuzz_target",
        "@com_google_fuzztest//centipede/testing:expensive_startup_fuzz_target",
        "@com_google_fuzztest//centipede/testing:fuzz_target_with_config",
        "@com_google_fuzztest//centipede/testing:seeded_fuzz_target",
        "@com_google_fuzztest//centipede/testing:test_fuzz_target",
        "@com_google_fuzztest//centipede/testing:test_input_filter",
    ],
    deps = [
        ":centipede_callbacks",
        ":centipede_default_callbacks",
        ":centipede_interface",
        ":environment",
        ":feature",
        ":mutation_input",
        ":runner_result",
        ":workdir",
        "@com_google_absl//absl/base:nullability",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/log",
        "@com_google_absl//absl/log:check",
        "@com_google_absl//absl/strings",
        "@com_google_fuzztest//common:defs",
        "@com_google_fuzztest//common:hash",
        "@com_google_fuzztest//common:logging",
        "@com_google_fuzztest//common:test_util",
        "@com_google_googletest//:gtest_main",
    ],
)

# Verify that the `:centipede` target indeed creates a binary with the
# expected name.
sh_test(
    name = "centipede_binary_test",
    srcs = ["centipede_binary_test.sh"],
    data = [
        ":centipede",
        ":test_util_sh",
    ],
)
